package com.sh.rpc.loadbalancer;

import com.sh.rpc.model.ServiceMetaInfo;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 一致性hash负载均衡器
 *
 * @author SH
 */
public class ConsistentHashLoaderBalancer implements LoadBalancer {


    // 一直hash环
    private final TreeMap<Integer, ServiceMetaInfo> virtualNodes = new TreeMap();

    // 虚拟节点数
    private static final int VIRTUAL_NODE_NUM = 100;


    @Override
    public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> serviceMetaInfoList) {
        if (serviceMetaInfoList.isEmpty()) {
            return null;
        }
        for (ServiceMetaInfo serviceMetaInfo : serviceMetaInfoList) {
            for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
                int hash = getHash(serviceMetaInfo.getServiceKey() + "#" + i);  // 计算hash值
                virtualNodes.put(hash, serviceMetaInfo);   // 将虚拟节点放入hash环
            }
        }
        int hash = getHash(requestParams);    // 计算请求参数的hash值
        // ceilingEntry(hash): 返回大于等于给定键的第一个条目，如果没有这样的条目，则返回null
        Map.Entry<Integer, ServiceMetaInfo> entry = virtualNodes.ceilingEntry(hash);
        if (entry == null) {
            // 如果没有找到大于等于给定键的条目，则返回第一个条目
            entry = virtualNodes.firstEntry();
        }
        return entry.getValue();
    }

    private int getHash(Object key) {
//        return (key.hashCode() & 0x7fffffff);
        return key.hashCode();
    }
}
